このページではOpenCV for Android関連のメモを書いています。
- 環境
OpenCV4Android 2.4.4
Galaxy S2 LTE(Android 2.3.6), AQUOS PHONE ZETA(Android 4.0.4)
カメラを利用した動画像処理
OpenCVでデバイスのカメラを利用した動画像処理を行う際の手順を整理しておきます。
- ''マニフェストファイルに権限の追加''
デバイスのカメラ機能を使えるように AndroidManifest.xml に権限を追加します(この設定はOpenCV固有のものではありません)。
基本
- ''レイアウトの定義''
OpenCVではカメラを扱う2つのクラス ''JavaCameraView'' と ''NativeCameraView'' が提供されています(両者の違いは後述)。これのどちらかをXMLレイアウトファイル(res/layout/*.xml)に配置します。 ここでは JavaCameraView を配置しています。利用できる属性は ''camera_id'' (any/front/back) と ''show_fps'' (true/false) です。camera_id には利用するカメラ(フロント/バックカメラ)を指定するのですが、any を指定しておけば自動的にカメラを判別してくれます。show_fps を true にすると画面左上にFPSと画角が表示されます。デバッグ時は有効にしておくと良いです。 - ''OpenCVライブラリの読み込みと初期化''
OpenCV Managerを使う場合、Activityの中でOpenCVライブラリの読み込みを行う ''OpenCVLoader.initAsync'' メソッドを呼び出す必要があります。このメソッドは非同期で実行されるので、読み込み完了後にUIスレッドで呼ばれるコールバックメソッドも併せて実装しておきます。 - ''CvCameraViewListener / CvCameraViewListener2 インタフェースの実装''
''CvCameraViewListener'' または ''CvCameraViewListener2'' インタフェースの以下の3つのメソッドを実装します。onCameraViewStarted onCameraViewStopped onCameraFrame
3つめの onCameraFrame メソッドに任意の画像処理を実装することになります。また、CvCameraViewListener と CvCameraViewListener2 の違いは onCameraFrame の引数のみで、onCameraViewStarted および onCameraViewStopped は共通です。 ''CvCameraViewFrame'' インタフェースは以下のようになっています。CvCameraViewListener2.onCameraFrame ではこのインタフェースを実装した JavaCameraFrame/NativeCameraFrame のインスタンスが渡されます。 キャプチャしたフレーム画像をそのままカメラプレビューに表示させるには、CvCameraViewListener.onCameraFrame の場合は引数の inputFrame をそのまま return し、CvCameraViewListener2.onCameraFrame の場合は inputFrame.rgba() を return します。
JavaCameraViewとNativeCameraViewの違い
JavaCameraView と NativeCameraView は両方とも CameraBridgeViewBase のサブクラスになっています。
JavaCameraView は android.hardware.Camera を利用した実装、NativeCameraView はOpenCVの VideoCapture を利用した実装という違いがあります。安定性という観点ではAndroid SDKの機能を利用した JavaCameraView の方が安定しているかと思われますが、そんなに気にしなくて大丈夫でしょう。
その他Tips
JavaCameraViewのLogCatがうるさい時
毎フレーム "Preview Frame received ~" という不要なログを書き出すので少し静かにしてもらいましょう。''JavaCameraView.onPreviewFrame'' メソッドの冒頭部分にある Log.i関数の呼び出しをコメントアウトしておくとスッキリします。編集後はOpenCV Libraryプロジェクトの再ビルドを忘れずに。
Mat.cloneではなくMat.copyToを使う
OpenCV4Android SDK 2.4.4時点では Mat.clone メソッドは不安定(正しく動作しない?)なため、Mat.copyTo メソッドを使ってデータのコピーを行った方が良いです。